#ifndef MOCHA_DETAIL_IMAGE_PLUGIN_H_INCLUDED
#define MOCHA_DETAIL_IMAGE_PLUGIN_H_INCLUDED

/**
 * @file
 */

#include <stdint.h>
#include "mocha/memory.h"
#include "mocha/plugin.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Image file format masks.
 */
typedef enum mocha_image_file_format_mask {
	/// Windows bitmap (DIB).
	mocha_image_file_format_bmp = 1,
	/// Graphics interchange format.
	mocha_image_file_format_gif = 1 << 1,
	/// Joint photographic experts group.
	mocha_image_file_format_jpeg = 1 << 2,
	/// Multiple-image network graphics.
	mocha_image_file_format_mng = 1 << 3,
	/// Portable network graphics.
	mocha_image_file_format_png = 1 << 4,
	/// Tagged image file format.
	mocha_image_file_format_tiff = 1 << 5
} mocha_image_file_format_mask;
/**
 * C compatible image implementation interface. Provides a pure C interface for communicating between binaries and for implementing pure C image plugins.
 */
typedef struct MOCHA_PACKED mocha_c_image_plugin {
	/**
	 * @return Plugin type name (as a vanilla string).
	 */
	const mocha_plugin_char_t *(*type_name)(const struct mocha_c_image_plugin *self); // const
	/**
	 * Loads the image from a file on disk (or part of a file system).
	 * @param path Path to the file.
	 * @return Zero or greater on success or a negative error code on failure.
	 */
	int32_t (*load_from_file)(struct mocha_c_image_plugin *self, const mocha_plugin_char_t *path);
	/**
	 * Loads the image from a file in memory. Attempts to resolve the file type of data.
	 * @param buffer Memory buffer containing the file contents.
	 * @param size Size of the buffer (in bytes).
	 * @return Zero or greater on success or a negative error code on failure.
	 */
	int32_t (*load_from_file_buffer)(struct mocha_c_image_plugin *self, int8_t *buffer, uint32_t size);
	/**
	 * Loads the image from a pixel buffer. The pixel format must be specified.
	 * @param buffer Memory buffer.
	 * @param width
	 * @param height
	 * @param red Red channel mask/position.
	 * @param green Green channel mask/position.
	 * @param blue Blue channel mask/position.
	 * @param alpha Alpha channel mask/position.
	 * @param type Pixel data type (e.g., byte, integer, etc.).
	 * @return Zero or greater on success or a negative error code on failure.
	 */
	int32_t (*load_from_pixels)(struct mocha_c_image_plugin *self, int8_t *buffer, uint32_t width, uint32_t height, int32_t red, int32_t green, int32_t blue, int32_t alpha, int8_t type);
	/**
	 * 
	 * Does not provide error codes.
	 */
	void (*free)(struct mocha_c_image_plugin *self);
	/**
	 * 
	 * @return Zero or greater on success or a negative error code on failure.
	 */
	int32_t (*crop)(struct mocha_c_image_plugin *self, int32_t x, int32_t y, int32_t width, int32_t height);
	/**
	 * 
	 * @return Zero or greater on success or a negative error code on failure.
	 */
	int32_t (*scale)(struct mocha_c_image_plugin *self, uint32_t width, uint32_t height);
	/**
	 * 
	 * @param red Red channel mask/position.
	 * @param green Green channel mask/position.
	 * @param blue Blue channel mask/position.
	 * @param alpha Alpha channel mask/position.
	 * @param type Pixel data type (e.g., byte, integer, etc.).
	 * @return Zero or greater on success or a negative error code on failure.
	 */
	int32_t (*convert)(struct mocha_c_image_plugin *self, int32_t red, int32_t green, int32_t blue, int32_t alpha, int8_t type);
	/**
	 * 
	 * The size of the buffer will be zero if an error occurs.
	 * Does not provide error codes.
	 */
	void (*read_write_pixels)(struct mocha_c_image_plugin *self, int8_t **buffer, uint32_t *size);
	/**
	 * 
	 * The size of the buffer will be zero if an error occurs.
	 * Does not provide error codes.
	 */
	void (*read_pixels)(const struct mocha_c_image_plugin *self, const int8_t **buffer, uint32_t *size); // const
	/**
	 * 
	 * @param red Red channel mask/position.
	 * @param green Green channel mask/position.
	 * @param blue Blue channel mask/position.
	 * @param alpha Alpha channel mask/position.
	 * @param type Pixel data type (e.g., byte, interger, etc.).
	 * @return 
	 */
	int32_t (*format)(const struct mocha_c_image_plugin *self, int32_t *red, int32_t *green, int32_t *blue, int32_t *alpha, int8_t *type); // const
	/**
	 * 
	 * Does not provide error codes.
	 * @return Width of the image in pixels or zero if there was an error.
	 */
	uint32_t (*width)(const struct mocha_c_image_plugin *self); // const
	/**
	 * 
	 * Does not provide error codes.
	 * @return Height of the image in pixels or zero if there was an error.
	 */
	uint32_t (*height)(const struct mocha_c_image_plugin *self); // const
	/**
	 * 
	 * @return Zero if not loaded, positive if loaded.
	 */
	int8_t (*loaded)(const struct mocha_c_image_plugin *self); // const
	///
	struct mocha_c_image_plugin *self;
} mocha_c_image_plugin;

#ifdef __cplusplus
} // extern "C"
#endif

#endif

